package com.ruoyi.app.service.impl;

import com.ruoyi.app.dto.BillAppealDto;
import com.ruoyi.app.dto.MemberInvoiceDto;
import com.ruoyi.app.mapper.ParkOrderMapper;
import com.ruoyi.app.service.IParkOrderService;
import com.ruoyi.app.vo.ParkingOrderVo;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.domain.MemberInvoice;
import com.ruoyi.domain.ParkingOrder;
import com.ruoyi.domain.ParkingOrderAppeal;
import com.ruoyi.framework.config.SmartParkingCloudConfig;
import com.ruoyi.mapper.MemberInvoiceMapper;
import com.ruoyi.mapper.ParkingOrderAppealMapper;
import com.ruoyi.mapper.ParkingOrderMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;

import javax.annotation.Resource;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * App端Service业务层处理
 * 
 * @author dongdong
 * @date 2025-09-11
 */
@Slf4j
@Service
public class ParkOrderServiceImpl implements IParkOrderService {

    @Autowired
    private TransactionTemplate transactionTemplate;
    @Resource
    private ParkingOrderMapper parkingOrderMapper;
    @Resource
    private MemberInvoiceMapper memberInvoiceMapper;
    @Resource
    private ParkingOrderAppealMapper parkingOrderAppealMapper;


    @Override
    public List<ParkingOrderVo> getParkOrderList(String uniqueId, Integer invoiceStatus) {
        List<ParkingOrder> parkingOrderList = parkingOrderMapper.selectParkingOrderListByUniqueId(uniqueId);
        List<ParkingOrderVo> list = ParkOrderMapper.INSTANCE.toParkingOrderVoList(parkingOrderList);
        List<ParkingOrderVo> voList;
        if (Objects.isNull(invoiceStatus)){
            voList = list.stream().map(e->{
                if(Objects.isNull(e.getEntryTime())){
                    e.setDuration("无入场时间");
                }else {
                    LocalDateTime exitTime = Objects.isNull(e.getExitTime()) ? e.getPayTime() : e.getExitTime();
                    e.setDuration(DateUtils.getFormattedDifference(e.getEntryTime(), exitTime));
                }
                return e;
            }).collect(Collectors.toList());
        }else {
            if (invoiceStatus.intValue() == 0){
                voList = list.stream().filter(e -> e.getInvoiceStatus().intValue() == 0).collect(Collectors.toList());
            }else {
                voList = list.stream().filter(e -> e.getInvoiceStatus().intValue() > 0).collect(Collectors.toList());
            }
        }
        return voList;
    }

    @Override
    public Map<String, Object> getParkOrder(String orderNo) {
        Map<String, Object> map = new HashMap<>();
        ParkingOrder parkingOrder = parkingOrderMapper.selectParkingOrderByOrderNo(orderNo);
        if(Objects.isNull(parkingOrder)){
            throw new RuntimeException("订单不存在");
        }
        ParkingOrderVo parkingOrderVo = ParkOrderMapper.INSTANCE.toParkingOrderVo(parkingOrder);
        if(Objects.isNull(parkingOrderVo.getEntryTime())){
            parkingOrderVo.setDuration("无入场时间");
        }else {
            LocalDateTime exitTime = Objects.isNull(parkingOrderVo.getExitTime()) ? parkingOrderVo.getPayTime() : parkingOrderVo.getExitTime();
            parkingOrderVo.setDuration(DateUtils.getFormattedDifference(parkingOrderVo.getEntryTime(), exitTime));
        }
        map.put("parkingOrder", parkingOrderVo);
        // 查询发票信息
        MemberInvoice memberInvoice = null;
        if(parkingOrder.getInvoiceStatus().intValue() > 0){
            memberInvoice = memberInvoiceMapper.selectMemberInvoiceByOrderNo(orderNo);
            memberInvoice.setInvoiceUrl(SmartParkingCloudConfig.BASE_URL + memberInvoice.getInvoiceUrl());
        }
        map.put("invoice", memberInvoice);
        return map;
    }

    @Override
    public Boolean applyInvoice(MemberInvoiceDto memberInvoiceDto) {
        MemberInvoice invoice = memberInvoiceMapper.selectMemberInvoiceByOrderNo(memberInvoiceDto.getOrderNo());
        if(Objects.nonNull(invoice)){
            throw new RuntimeException("该订单已申请开票");
        }
        ParkingOrder parkingOrder = parkingOrderMapper.selectParkingOrderByOrderNo(memberInvoiceDto.getOrderNo());
        if (Objects.isNull(parkingOrder)){
            throw new RuntimeException("订单不存在");
        }
        MemberInvoice memberInvoice = ParkOrderMapper.INSTANCE.toMemberInvoice(memberInvoiceDto);
        String applyId = StringUtils.generateInvoiceApplyId();
        memberInvoice.setApplyId(applyId);
        memberInvoice.setAmount(parkingOrder.getPayAmount());
        memberInvoice.setChannel(1);
        memberInvoice.setStatus(1);
        Boolean execute = transactionTemplate.execute(e -> {
            int res = memberInvoiceMapper.insertMemberInvoice(memberInvoice);
            if(res > 0){
                parkingOrder.setInvoiceStatus(1);
                parkingOrderMapper.updateParkingOrder(parkingOrder);
            }
            return res == 1;
        });
        if (!execute){
            throw new RuntimeException("申请开票失败");
        }
        return execute;
    }

    @Override
    public Boolean billAppeal(BillAppealDto billAppealDto) {
        ParkingOrderAppeal appeal = parkingOrderAppealMapper.selectParkingOrderAppealByOrderNo(billAppealDto.getOrderNo());
        if (Objects.nonNull(appeal)){
            throw new RuntimeException("该订单已申诉");
        }
        ParkingOrderAppeal parkingOrderAppeal = ParkOrderMapper.INSTANCE.toParkingOrderAppeal(billAppealDto);
        parkingOrderAppeal.setAppealStatus(0);
        parkingOrderAppeal.setAppealTime(new Date());
        int res = parkingOrderAppealMapper.insertParkingOrderAppeal(parkingOrderAppeal);
        return res == 1;
    }

}
